package com.ldh.mod4j.businessdomain.serializer;

import com.google.inject.Inject;
import com.google.inject.Provider;
import com.ldh.mod4j.businessdomain.businessDomainDsl.Association;
import com.ldh.mod4j.businessdomain.businessDomainDsl.BoolProperty;
import com.ldh.mod4j.businessdomain.businessDomainDsl.BusinessClass;
import com.ldh.mod4j.businessdomain.businessDomainDsl.BusinessDomainDslPackage;
import com.ldh.mod4j.businessdomain.businessDomainDsl.BusinessDomainModel;
import com.ldh.mod4j.businessdomain.businessDomainDsl.BusinessRule;
import com.ldh.mod4j.businessdomain.businessDomainDsl.DateTimeProperty;
import com.ldh.mod4j.businessdomain.businessDomainDsl.DecimalProperty;
import com.ldh.mod4j.businessdomain.businessDomainDsl.Enumeration;
import com.ldh.mod4j.businessdomain.businessDomainDsl.EnumerationLiteral;
import com.ldh.mod4j.businessdomain.businessDomainDsl.EnumerationProperty;
import com.ldh.mod4j.businessdomain.businessDomainDsl.IntegerProperty;
import com.ldh.mod4j.businessdomain.businessDomainDsl.StringProperty;
import com.ldh.mod4j.businessdomain.businessDomainDsl.UniqueRule;
import com.ldh.mod4j.businessdomain.services.BusinessDomainDslGrammarAccess;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.serializer.acceptor.ISemanticSequenceAcceptor;
import org.eclipse.xtext.serializer.acceptor.SequenceFeeder;
import org.eclipse.xtext.serializer.diagnostic.ISemanticSequencerDiagnosticProvider;
import org.eclipse.xtext.serializer.diagnostic.ISerializationDiagnostic.Acceptor;
import org.eclipse.xtext.serializer.sequencer.AbstractSemanticSequencer;
import org.eclipse.xtext.serializer.sequencer.GenericSequencer;
import org.eclipse.xtext.serializer.sequencer.ISemanticNodeProvider.INodesForEObjectProvider;
import org.eclipse.xtext.serializer.sequencer.ISemanticSequencer;
import org.eclipse.xtext.serializer.sequencer.ITransientValueService;
import org.eclipse.xtext.serializer.sequencer.ITransientValueService.ValueTransient;

@SuppressWarnings("restriction")
public class AbstractBusinessDomainDslSemanticSequencer extends AbstractSemanticSequencer {

	@Inject
	protected BusinessDomainDslGrammarAccess grammarAccess;
	
	@Inject
	protected ISemanticSequencerDiagnosticProvider diagnosticProvider;
	
	@Inject
	protected ITransientValueService transientValues;
	
	@Inject
	@GenericSequencer
	protected Provider<ISemanticSequencer> genericSequencerProvider;
	
	protected ISemanticSequencer genericSequencer;
	
	
	@Override
	public void init(ISemanticSequencer sequencer, ISemanticSequenceAcceptor sequenceAcceptor, Acceptor errorAcceptor) {
		super.init(sequencer, sequenceAcceptor, errorAcceptor);
		this.genericSequencer = genericSequencerProvider.get();
		this.genericSequencer.init(sequencer, sequenceAcceptor, errorAcceptor);
	}
	
	public void createSequence(EObject context, EObject semanticObject) {
		if(semanticObject.eClass().getEPackage() == BusinessDomainDslPackage.eINSTANCE) switch(semanticObject.eClass().getClassifierID()) {
			case BusinessDomainDslPackage.ASSOCIATION:
				if(context == grammarAccess.getAssociationRule()) {
					sequence_Association(context, (Association) semanticObject); 
					return; 
				}
				else break;
			case BusinessDomainDslPackage.BOOL_PROPERTY:
				if(context == grammarAccess.getBoolPropertyRule()) {
					sequence_BoolProperty(context, (BoolProperty) semanticObject); 
					return; 
				}
				else if(context == grammarAccess.getPropertyRule()) {
					sequence_Property(context, (BoolProperty) semanticObject); 
					return; 
				}
				else break;
			case BusinessDomainDslPackage.BUSINESS_CLASS:
				if(context == grammarAccess.getBusinessClassRule()) {
					sequence_BusinessClass(context, (BusinessClass) semanticObject); 
					return; 
				}
				else break;
			case BusinessDomainDslPackage.BUSINESS_DOMAIN_MODEL:
				if(context == grammarAccess.getBusinessDomainModelRule()) {
					sequence_BusinessDomainModel(context, (BusinessDomainModel) semanticObject); 
					return; 
				}
				else break;
			case BusinessDomainDslPackage.BUSINESS_RULE:
				if(context == grammarAccess.getAbstractBusinessRuleRule() ||
				   context == grammarAccess.getBusinessRuleRule()) {
					sequence_BusinessRule(context, (BusinessRule) semanticObject); 
					return; 
				}
				else break;
			case BusinessDomainDslPackage.DATE_TIME_PROPERTY:
				if(context == grammarAccess.getDateTimePropertyRule()) {
					sequence_DateTimeProperty(context, (DateTimeProperty) semanticObject); 
					return; 
				}
				else if(context == grammarAccess.getPropertyRule()) {
					sequence_Property(context, (DateTimeProperty) semanticObject); 
					return; 
				}
				else break;
			case BusinessDomainDslPackage.DECIMAL_PROPERTY:
				if(context == grammarAccess.getDecimalPropertyRule()) {
					sequence_DecimalProperty(context, (DecimalProperty) semanticObject); 
					return; 
				}
				else if(context == grammarAccess.getPropertyRule()) {
					sequence_Property(context, (DecimalProperty) semanticObject); 
					return; 
				}
				else break;
			case BusinessDomainDslPackage.ENUMERATION:
				if(context == grammarAccess.getEnumerationRule()) {
					sequence_Enumeration(context, (Enumeration) semanticObject); 
					return; 
				}
				else break;
			case BusinessDomainDslPackage.ENUMERATION_LITERAL:
				if(context == grammarAccess.getEnumerationLiteralRule()) {
					sequence_EnumerationLiteral(context, (EnumerationLiteral) semanticObject); 
					return; 
				}
				else break;
			case BusinessDomainDslPackage.ENUMERATION_PROPERTY:
				if(context == grammarAccess.getEnumerationPropertyRule()) {
					sequence_EnumerationProperty(context, (EnumerationProperty) semanticObject); 
					return; 
				}
				else if(context == grammarAccess.getPropertyRule()) {
					sequence_Property(context, (EnumerationProperty) semanticObject); 
					return; 
				}
				else break;
			case BusinessDomainDslPackage.INTEGER_PROPERTY:
				if(context == grammarAccess.getIntegerPropertyRule()) {
					sequence_IntegerProperty(context, (IntegerProperty) semanticObject); 
					return; 
				}
				else if(context == grammarAccess.getPropertyRule()) {
					sequence_Property(context, (IntegerProperty) semanticObject); 
					return; 
				}
				else break;
			case BusinessDomainDslPackage.STRING_PROPERTY:
				if(context == grammarAccess.getPropertyRule()) {
					sequence_Property(context, (StringProperty) semanticObject); 
					return; 
				}
				else if(context == grammarAccess.getStringPropertyRule()) {
					sequence_StringProperty(context, (StringProperty) semanticObject); 
					return; 
				}
				else break;
			case BusinessDomainDslPackage.UNIQUE_RULE:
				if(context == grammarAccess.getAbstractBusinessRuleRule() ||
				   context == grammarAccess.getUniqueRuleRule()) {
					sequence_UniqueRule(context, (UniqueRule) semanticObject); 
					return; 
				}
				else break;
			}
		if (errorAcceptor != null) errorAcceptor.accept(diagnosticProvider.createInvalidContextOrTypeDiagnostic(semanticObject, context));
	}
	
	/**
	 * Constraint:
	 *     (
	 *         description=STRING? 
	 *         source=[BusinessClass|ID] 
	 *         sourceRoleName=ID 
	 *         sourceMultiplicity=Multiplicity 
	 *         bidirectional?='<->'? 
	 *         targetMultiplicity=Multiplicity 
	 *         target=[BusinessClass|ID] 
	 *         targetRoleName=ID 
	 *         ordered?='ordered'?
	 *     )
	 *
	 * Features:
	 *    description[0, 1]
	 *    source[1, 1]
	 *    sourceRoleName[1, 1]
	 *    sourceMultiplicity[1, 1]
	 *    bidirectional[0, 1]
	 *    targetMultiplicity[1, 1]
	 *    target[1, 1]
	 *    targetRoleName[1, 1]
	 *    ordered[0, 1]
	 */
	protected void sequence_Association(EObject context, Association semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (description=STRING? dataType='boolean' name=ID (hasDefault?='default' defaultValue?='true'?)?)
	 *
	 * Features:
	 *    description[0, 1]
	 *    name[1, 1]
	 *    dataType[1, 1]
	 *    hasDefault[0, 1]
	 *         MANDATORY_IF_SET defaultValue
	 *    defaultValue[0, 1]
	 *         EXCLUDE_IF_UNSET hasDefault
	 */
	protected void sequence_BoolProperty(EObject context, BoolProperty semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (description=STRING? name=ID superclass=[BusinessClass|ID]? properties+=Property* businessRules+=AbstractBusinessRule*)
	 *
	 * Features:
	 *    description[0, 1]
	 *    name[1, 1]
	 *    superclass[0, 1]
	 *    properties[0, *]
	 *    businessRules[0, *]
	 */
	protected void sequence_BusinessClass(EObject context, BusinessClass semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (description=STRING? name=ID (types+=BusinessClass | enumerations+=Enumeration | associations+=Association)*)
	 *
	 * Features:
	 *    description[0, 1]
	 *    name[1, 1]
	 *    types[0, *]
	 *    enumerations[0, *]
	 *    associations[0, *]
	 */
	protected void sequence_BusinessDomainModel(EObject context, BusinessDomainModel semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (description=STRING? name=ID)
	 *
	 * Features:
	 *    description[0, 1]
	 *    name[1, 1]
	 */
	protected void sequence_BusinessRule(EObject context, BusinessRule semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (description=STRING? dataType='datetime' name=ID (hasDefault?='default' defaultValue=STRING)?)
	 *
	 * Features:
	 *    description[0, 1]
	 *    name[1, 1]
	 *    dataType[1, 1]
	 *    hasDefault[0, 1]
	 *         EXCLUDE_IF_UNSET defaultValue
	 *         MANDATORY_IF_SET defaultValue
	 *    defaultValue[0, 1]
	 *         EXCLUDE_IF_UNSET hasDefault
	 *         MANDATORY_IF_SET hasDefault
	 */
	protected void sequence_DateTimeProperty(EObject context, DateTimeProperty semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (description=STRING? dataType='decimal' name=ID precision=INT? scale=INT?)
	 *
	 * Features:
	 *    description[0, 1]
	 *    name[1, 1]
	 *    dataType[1, 1]
	 *    precision[0, 1]
	 *    scale[0, 1]
	 */
	protected void sequence_DecimalProperty(EObject context, DecimalProperty semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID persistedValue=INT)
	 *
	 * Features:
	 *    name[1, 1]
	 *    persistedValue[1, 1]
	 */
	protected void sequence_EnumerationLiteral(EObject context, EnumerationLiteral semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, BusinessDomainDslPackage.Literals.ENUMERATION_LITERAL__NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, BusinessDomainDslPackage.Literals.ENUMERATION_LITERAL__NAME));
			if(transientValues.isValueTransient(semanticObject, BusinessDomainDslPackage.Literals.ENUMERATION_LITERAL__PERSISTED_VALUE) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, BusinessDomainDslPackage.Literals.ENUMERATION_LITERAL__PERSISTED_VALUE));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getEnumerationLiteralAccess().getNameIDTerminalRuleCall_0_0(), semanticObject.getName());
		feeder.accept(grammarAccess.getEnumerationLiteralAccess().getPersistedValueINTTerminalRuleCall_1_1_0(), semanticObject.getPersistedValue());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     (description=STRING? type=[Enumeration|ID] name=ID (hasDefault?='default' defaultValueAsString=ID)?)
	 *
	 * Features:
	 *    description[0, 1]
	 *    name[1, 1]
	 *    type[1, 1]
	 *    hasDefault[0, 1]
	 *         EXCLUDE_IF_UNSET defaultValueAsString
	 *         MANDATORY_IF_SET defaultValueAsString
	 *    defaultValueAsString[0, 1]
	 *         EXCLUDE_IF_UNSET hasDefault
	 *         MANDATORY_IF_SET hasDefault
	 */
	protected void sequence_EnumerationProperty(EObject context, EnumerationProperty semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (description=STRING? name=ID enumerationLiterals+=EnumerationLiteral+)
	 *
	 * Features:
	 *    description[0, 1]
	 *    name[1, 1]
	 *    enumerationLiterals[1, *]
	 */
	protected void sequence_Enumeration(EObject context, Enumeration semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (
	 *         description=STRING? 
	 *         dataType='integer' 
	 *         name=ID 
	 *         (hasDefault?='default' defaultValue=INT)? 
	 *         minValue=INT? 
	 *         maxValue=INT?
	 *     )
	 *
	 * Features:
	 *    description[0, 1]
	 *    name[1, 1]
	 *    dataType[1, 1]
	 *    hasDefault[0, 1]
	 *         EXCLUDE_IF_UNSET defaultValue
	 *         MANDATORY_IF_SET defaultValue
	 *    defaultValue[0, 1]
	 *         EXCLUDE_IF_UNSET hasDefault
	 *         MANDATORY_IF_SET hasDefault
	 *    minValue[0, 1]
	 *    maxValue[0, 1]
	 */
	protected void sequence_IntegerProperty(EObject context, IntegerProperty semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (
	 *         description=STRING? 
	 *         dataType='boolean' 
	 *         name=ID 
	 *         (hasDefault?='default' defaultValue?='true'?)? 
	 *         nullable?='nullable'? 
	 *         (derived?='derived' writable?='writable'?)?
	 *     )
	 *
	 * Features:
	 *    nullable[0, 1]
	 *    derived[0, 1]
	 *         MANDATORY_IF_SET writable
	 *    writable[0, 1]
	 *         EXCLUDE_IF_UNSET derived
	 *    description[0, 1]
	 *    name[1, 1]
	 *    dataType[1, 1]
	 *    hasDefault[0, 1]
	 *         MANDATORY_IF_SET defaultValue
	 *    defaultValue[0, 1]
	 *         EXCLUDE_IF_UNSET hasDefault
	 */
	protected void sequence_Property(EObject context, BoolProperty semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (
	 *         description=STRING? 
	 *         dataType='datetime' 
	 *         name=ID 
	 *         (hasDefault?='default' defaultValue=STRING)? 
	 *         nullable?='nullable'? 
	 *         (derived?='derived' writable?='writable'?)?
	 *     )
	 *
	 * Features:
	 *    nullable[0, 1]
	 *    derived[0, 1]
	 *         MANDATORY_IF_SET writable
	 *    writable[0, 1]
	 *         EXCLUDE_IF_UNSET derived
	 *    description[0, 1]
	 *    name[1, 1]
	 *    dataType[1, 1]
	 *    hasDefault[0, 1]
	 *         EXCLUDE_IF_UNSET defaultValue
	 *         MANDATORY_IF_SET defaultValue
	 *    defaultValue[0, 1]
	 *         EXCLUDE_IF_UNSET hasDefault
	 *         MANDATORY_IF_SET hasDefault
	 */
	protected void sequence_Property(EObject context, DateTimeProperty semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (
	 *         description=STRING? 
	 *         dataType='decimal' 
	 *         name=ID 
	 *         precision=INT? 
	 *         scale=INT? 
	 *         nullable?='nullable'? 
	 *         (derived?='derived' writable?='writable'?)?
	 *     )
	 *
	 * Features:
	 *    nullable[0, 1]
	 *    derived[0, 1]
	 *         MANDATORY_IF_SET writable
	 *    writable[0, 1]
	 *         EXCLUDE_IF_UNSET derived
	 *    description[0, 1]
	 *    name[1, 1]
	 *    dataType[1, 1]
	 *    precision[0, 1]
	 *    scale[0, 1]
	 */
	protected void sequence_Property(EObject context, DecimalProperty semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (
	 *         description=STRING? 
	 *         type=[Enumeration|ID] 
	 *         name=ID 
	 *         (hasDefault?='default' defaultValueAsString=ID)? 
	 *         nullable?='nullable'? 
	 *         (derived?='derived' writable?='writable'?)?
	 *     )
	 *
	 * Features:
	 *    nullable[0, 1]
	 *    derived[0, 1]
	 *         MANDATORY_IF_SET writable
	 *    writable[0, 1]
	 *         EXCLUDE_IF_UNSET derived
	 *    description[0, 1]
	 *    name[1, 1]
	 *    type[1, 1]
	 *    hasDefault[0, 1]
	 *         EXCLUDE_IF_UNSET defaultValueAsString
	 *         MANDATORY_IF_SET defaultValueAsString
	 *    defaultValueAsString[0, 1]
	 *         EXCLUDE_IF_UNSET hasDefault
	 *         MANDATORY_IF_SET hasDefault
	 */
	protected void sequence_Property(EObject context, EnumerationProperty semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (
	 *         description=STRING? 
	 *         dataType='integer' 
	 *         name=ID 
	 *         (hasDefault?='default' defaultValue=INT)? 
	 *         minValue=INT? 
	 *         maxValue=INT? 
	 *         nullable?='nullable'? 
	 *         (derived?='derived' writable?='writable'?)?
	 *     )
	 *
	 * Features:
	 *    nullable[0, 1]
	 *    derived[0, 1]
	 *         MANDATORY_IF_SET writable
	 *    writable[0, 1]
	 *         EXCLUDE_IF_UNSET derived
	 *    description[0, 1]
	 *    name[1, 1]
	 *    dataType[1, 1]
	 *    hasDefault[0, 1]
	 *         EXCLUDE_IF_UNSET defaultValue
	 *         MANDATORY_IF_SET defaultValue
	 *    defaultValue[0, 1]
	 *         EXCLUDE_IF_UNSET hasDefault
	 *         MANDATORY_IF_SET hasDefault
	 *    minValue[0, 1]
	 *    maxValue[0, 1]
	 */
	protected void sequence_Property(EObject context, IntegerProperty semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (
	 *         description=STRING? 
	 *         dataType='string' 
	 *         name=ID 
	 *         (hasDefault?='default' defaultValue=STRING)? 
	 *         minLength=INT? 
	 *         maxLength=INT? 
	 *         regularExpression=STRING? 
	 *         nullable?='nullable'? 
	 *         (derived?='derived' writable?='writable'?)?
	 *     )
	 *
	 * Features:
	 *    nullable[0, 1]
	 *    derived[0, 1]
	 *         MANDATORY_IF_SET writable
	 *    writable[0, 1]
	 *         EXCLUDE_IF_UNSET derived
	 *    description[0, 1]
	 *    name[1, 1]
	 *    dataType[1, 1]
	 *    hasDefault[0, 1]
	 *         EXCLUDE_IF_UNSET defaultValue
	 *         MANDATORY_IF_SET defaultValue
	 *    defaultValue[0, 1]
	 *         EXCLUDE_IF_UNSET hasDefault
	 *         MANDATORY_IF_SET hasDefault
	 *    minLength[0, 1]
	 *    maxLength[0, 1]
	 *    regularExpression[0, 1]
	 */
	protected void sequence_Property(EObject context, StringProperty semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (
	 *         description=STRING? 
	 *         dataType='string' 
	 *         name=ID 
	 *         (hasDefault?='default' defaultValue=STRING)? 
	 *         minLength=INT? 
	 *         maxLength=INT? 
	 *         regularExpression=STRING?
	 *     )
	 *
	 * Features:
	 *    description[0, 1]
	 *    name[1, 1]
	 *    dataType[1, 1]
	 *    hasDefault[0, 1]
	 *         EXCLUDE_IF_UNSET defaultValue
	 *         MANDATORY_IF_SET defaultValue
	 *    defaultValue[0, 1]
	 *         EXCLUDE_IF_UNSET hasDefault
	 *         MANDATORY_IF_SET hasDefault
	 *    minLength[0, 1]
	 *    maxLength[0, 1]
	 *    regularExpression[0, 1]
	 */
	protected void sequence_StringProperty(EObject context, StringProperty semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (description=STRING? name=ID properties+=[Property|ID] properties+=[Property|ID]*)
	 *
	 * Features:
	 *    description[0, 1]
	 *    name[1, 1]
	 *    properties[1, *]
	 */
	protected void sequence_UniqueRule(EObject context, UniqueRule semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
}
